use std::sync::Arc;
use crate::dto;
use crate::http::client::{error, rpc};
use crate::http::route;
use reqwest::Method;
use wanmesh_common::dto::ExistsResponseData;

pub struct EndpointClient {
    rpc_client: Arc<rpc::Client>,
}

impl EndpointClient {
    pub fn new(rpc_client: Arc<rpc::Client>) -> Self {
        Self { rpc_client }
    }

    pub async fn add(
        &self,
        request: &dto::endpoint::AddRequest,
    ) -> Result<dto::core::endpoint::action::AddResponseData, error::Error> {
        self.rpc_client
            .call(
                route::PATH_ENDPOINT_ADD,
                Method::POST,
                request,
                rpc::CallOptions::default(),
            )
            .await
    }

    pub async fn list(
        &self,
        request: &dto::endpoint::action::ListRequest,
    ) -> Result<dto::endpoint::action::ListResponseData, error::Error> {
        self.rpc_client
            .call(
                route::PATH_ENDPOINT_LIST,
                Method::POST,
                request,
                rpc::CallOptions::default(),
            )
            .await
    }

    pub async fn list_info(
        &self,
        request: &dto::endpoint::action::ListRequest,
    ) -> Result<dto::endpoint::ListInfoResponseData, error::Error> {
        self.rpc_client
            .call(
                route::PATH_ENDPOINT_LIST_INFO,
                Method::POST,
                request,
                rpc::CallOptions::default(),
            )
            .await
    }

    pub async fn get(
        &self,
        request: &dto::endpoint::action::GetRequest,
    ) -> Result<dto::core::endpoint::Endpoint, error::Error> {
        self.rpc_client
            .call(
                route::PATH_ENDPOINT_GET,
                Method::POST,
                request,
                rpc::CallOptions::default(),
            )
            .await
    }

    pub async fn get_info(
        &self,
        request: &dto::endpoint::action::GetRequest,
    ) -> Result<dto::endpoint::EndpointInfo, error::Error> {
        self.rpc_client
            .call(
                route::PATH_ENDPOINT_GET_INFO,
                Method::POST,
                request,
                rpc::CallOptions::default(),
            )
            .await
    }

    pub async fn update(
        &self,
        request: &dto::endpoint::action::UpdateRequest,
    ) -> Result<(), error::Error> {
        self.rpc_client
            .call(
                route::PATH_ENDPOINT_UPDATE,
                Method::POST,
                request,
                rpc::CallOptions::default(),
            )
            .await
    }

    pub async fn delete(
        &self,
        request: &dto::endpoint::action::DeleteRequest,
    ) -> Result<(), error::Error> {
        self.rpc_client
            .call(
                route::PATH_ENDPOINT_DELETE,
                Method::POST,
                request,
                rpc::CallOptions::default(),
            )
            .await
    }

    pub async fn exists(
        &self,
        request: &dto::endpoint::action::ExistsRequest,
    ) -> Result<ExistsResponseData, error::Error> {
        self.rpc_client
            .call(
                route::PATH_ENDPOINT_EXISTS,
                Method::POST,
                request,
                rpc::CallOptions::default(),
            )
            .await
    }
}
